﻿


using IotClientService;
using IotContract.Configs;
using IotContract.Consts;
using IotContract.Dtos.Clients;
using IotContract.Dtos.Servers;
using IotContract.Dtos.Servers.Pushs;
using IotContract.Enums;
using IotContract.Interfaces;
using IotContract.Interfaces.Fmt;
using IotContract.Models;
using IotContract.Models.Clients;
using IotContract.Models.Clients.Hks;
using IotContract.Models.Process;
using IotContract.Models.Webs;
using IotServerService.Entities;
using Mapster;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Config;
using XT.Common.Extensions;
using XT.Common.Services;


namespace IotServerService.Services.Datas;
/// <summary>
/// 连接数据服务
/// </summary>
public class ConnectDataService:IConnectDataService
{
    

    #region Service
    private readonly DbService _dbService;
    private readonly ILogService    _logService;

    private readonly IServerMainManager _manager;

    private readonly IRemoteHttpService _remoteHttpService;

    public AddressConfig AddressConfig { get; set; }
    #endregion

    public ConnectDataService(DbService dbService,ILogService logService,IServerMainManager manager)
    {
        _dbService = dbService;
        _logService = logService;
        _manager = manager;
        AddressConfig=AppSettings.GetObjData<AddressConfig>();
    }

    /// <summary>
    /// 提交状态,返回是否启用
    /// </summary>
    /// <returns></returns>
    public async Task<int> CommitStatus(ClientStatusCommand clientStatus)
    {
        var data = WindowProcessService.GetCupAndRam();
        // 进行状态传输
        var status = await new Func<Task<ProgramStatus>>(() => _dbService.AddProgramStatus(new IotContract.Models.Clients.ClientStatusCommand
        {
            StatusDes = clientStatus.StatusDes.IsNullOrEmpty() ? clientStatus.Status.ToDescription() : clientStatus.StatusDes,
            Cpu = data.Item1,
            Ram = data.Item2,
            ProgramId = clientStatus.ProgramId,
            Status = clientStatus.Status,
            Remark=clientStatus.Remark
        })).ProtectFunc();
        if (status.Item2.IsNotNullOrEmpty())
        {
            _logService.Log($"{clientStatus.Name} {status.Item2}");
            return 0;
        }
        else
        {
            // 是启用状态
            return status.Item1.IsEnable;
        }
    }
    /// <summary>
    /// 添加程序
    /// </summary>
    /// <param name="clientConnect"></param>
    /// <returns></returns>
    public async Task<(IotProgramDto, string)> AddProgram(ClientConnectCommand clientConnect)
    {
        // 开始进行数据添加
        var programResult = await new Func<Task<ProgramInfo>>(() => _dbService.AddProgram(clientConnect)).ProtectFunc();
        return (programResult.Item1.Adapt<IotProgramDto>(),programResult.Item2);

    }
    /// <summary>
    /// 读取控制指令
    /// </summary>
    /// <param name="programId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async IAsyncEnumerable<ClientControlCommand> ReadControl(long programId,CancellationToken token)
    {
       
        while (!token.IsCancellationRequested)
        {
            var datas = await _manager.ReadControl(programId);
           foreach(var data in datas)
            {
                yield return data;
            }
           

            await Task.Delay(100);
        }
    }


    /// <summary>
    /// 向服务端推送设备数据
    /// </summary>
    /// <param name="groups"></param>
    /// <returns></returns>
    public async Task<List<OperationWriteCommand>> PushEquips<T>(List<T> equips) where T:IPushEquip
    {
        List<IPushEquip> pushs = new List<IPushEquip>();
        equips.ForEach(x =>
        {
            pushs.Add(x);
        });
       var datas=await _manager.PushEquips(pushs);
        return datas;
    }

    /// <summary>
    /// 获取设备数据
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<(List<IotEquipDto>,string)> GetEquips(ClientRequestCommand command)
    {
        var programResult = await new Func<Task<List<IotEquipDto>>>(() => _dbService.GetEquips(command)).ProtectFunc();
        return programResult;
    }
    
    /// <summary>
    /// 获取设备点位数据
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<(List<EquipTagDto>, string)> GetEquipTags(ClientRequestCommand command)
    {
        var programResult = await new Func<Task<List<EquipTagDto>>>(() => _dbService.GetEquipTags(command)).ProtectFunc();
        return programResult;
    }



   



    /// <summary>
    /// 获取调度数据
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<List<ProcessBaseData>> GetProcessDatas(ProcessProviderCommand command)
    {
       return await _manager.GetProcessDatas(command);
    }
    /// <summary>
    /// 添加任务
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<string> AddProcessJob(ProcessJobCommand command)
    {
       return await _manager.AddProcessJob(command.Job, command.ProviderType);
    }
    /// <summary>
    /// 添加控制命令
    /// </summary>
    /// <param name="control"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<string> AddWebControl(WebControlModel control)
    {
        if (control.ControlType > 3)
        {
            return "Not Match CotrolType";
        }
        try
        {
            var equip = await _dbService.GetEquip(control.EquipNum.ToString());

            // 写入命令
            if (control.ControlType == 3)
            {
               await _manager.AddWrite(new OperationWriteCommand
                {
                    Value = control.Value,
                    EquipId = equip.Id,
                    ProtobufType = equip.ProtobufType,

                });
            }
            else
            {
                await _manager.AddControl(new ClientControlCommand
                {
                    ControlType = control.ControlType==1?ProgramControlType.Connect:ProgramControlType.DisConnect,
                    EquipId = equip.Id,
                    ProtobufType = equip.ProtobufType,
                    ProgramId=equip.ProgramId

                });
            }
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
        return string.Empty;
    }




    #region 弃用

    /// <summary>
    /// 提交设备报警
    /// </summary>
    /// <param name="iotEquipWarnDto"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> CommitFireWarn(IotEquipWarnDto iotEquipWarnDto)
    {



        await _manager.AddWarns(new List<IotEquipWarnDto> { iotEquipWarnDto });
        if (iotEquipWarnDto.EquipType == IotEquipType.FMT.ToString())
        {
            if (iotEquipWarnDto.Data.IsNotNullOrEmpty())
            {
                var stages = iotEquipWarnDto.Data.Split('*');
                if (stages.Length >= 2)
                {
                    int.TryParse(stages[1], out int stage);
                    // 添加结果
                    var result = await _remoteHttpService.CommitFmtWarn(iotEquipWarnDto.ErrorCode, stage);

                    return new GrpcReturn<string>
                    {
                        IsSuccess = result.Flag
                    };
                }

            }


        }







        return new GrpcReturn<string>
        {
            IsSuccess = true
        };

    }
    /// <summary>
    /// 提交充放电结果
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> CommitChargeFMTResult(ChargeTrayResult data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.CommitChargeFMTResult(data);
        if (result.Flag)
        {


            return new GrpcReturn<string>
            {
                Data = result.Data,
                IsSuccess = true
            };
        }
        else
        {
            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode = $" {data.Stage} {IotMsgConst.HkCommitError}，{result.Code},{result.Msg}",
                    EquipType = IotEquipType.FMT.ToString(),
                    ProtobufType=IotProtobufType.HK_OCVFMT.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.GroupNumber.ToString()
            } });

            return new GrpcReturn<string>
            {
                Msg = result.Msg,
            };
        }
    }
    /// <summary>
    /// 提交充放电移库
    /// </summary>
    /// <param name="moveInstruct"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> CommitFmtMove(StageMoveInstruct moveInstruct)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.CommitFmtMove(moveInstruct);
        if (result.Flag)
        {
            return new GrpcReturn<string>
            {
                Data = result.Data,
                IsSuccess = true
            };
        }
        else
        {
            return new GrpcReturn<string>
            {
                Msg = result.Msg
            };
        }
    }
    /// <summary>
    /// OCV获取组盘信息
    /// </summary>
    /// <param name="trayDefineInstruct"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<TrayCellStatus>> GetTrayCellStatus(TrayDefineInstruct tray)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<TrayCellStatus>
            {
                Msg = "Timeout",
                Code = 400
            };
        }
        var result = await _remoteHttpService.GetTrayGroup(tray.TrayNo, tray.StageNo, tray.GroupNumber);
        if (result.Flag)
        {
            return new GrpcReturn<TrayCellStatus>
            {
                Data = result.Data,
                IsSuccess = true
            };
        }
        else
        {

            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode = $"{tray.TrayNo} {IotMsgConst.OcvCommitError}，{result.Msg} ",
                    EquipType = IotEquipType.OCV.ToString(),
                    ProtobufType=IotProtobufType.HK_OCVFMT.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = tray.GroupNumber.ToString()
            } });
            return new GrpcReturn<TrayCellStatus>
            {
                Msg = result.Msg,
                Code = result.Code
            };
        }
    }
    /// <summary>
    /// 提交ocv测试结果
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<OCVCellMain>> CommitOcvResult(OCVTrayResult data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<OCVCellMain>
            {
                Msg = "Timeout",
                Code = 400
            };
        }
        var result = await _remoteHttpService.CommitOcvResult(data);
        if (result.Flag)
        {

            return new GrpcReturn<OCVCellMain>
            {
                Data = result.Data,
                Code = result.Code,
                IsSuccess = true
            };



        }
        else
        {


            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode = $"{data.TrayNo} {IotMsgConst.OcvCommitError}，{result.Msg} ",
                    EquipType = IotEquipType.OCV.ToString(),
                    ProtobufType=IotProtobufType.HK_OCVFMT.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.GroupNumber.ToString()
            } });
            return new GrpcReturn<OCVCellMain>
            {
                Msg = result.Msg,
                Code = result.Code
            };
        }
    }
    /// <summary>
    /// 获取复测配方
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> GetReTestChargeFMT(HkWriteInstruct data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.GetReTestChargeFMT(data.TrayID);


        if (result.Flag)
        {

            result.Data.TrayNo = data.TrayID;
            result.Data.StageNo = data.Stage.ToString();
            var str = result.Data.ToString();
            return new GrpcReturn<string>
            {
                Data = str,
                IsSuccess = true
            };
        }
        else
        {
            data.ErrorMsg = $"{data.Stage} {data.TrayID} {IotMsgConst.FmtReTestError}，{result.Msg} ";


            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode = data.ErrorMsg,
                    EquipType = IotEquipType.FMT.ToString(),
                    ProtobufType=IotProtobufType.HK_OCVFMT.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.Num.ToString()
            } });
            return new GrpcReturn<string>
            {
                Msg = result.Msg,
            };
        }
    }
    /// <summary>
    /// 获取充放电配方
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> GetChargeFMTData(HkWriteInstruct data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.GetChargeFMTData(data.TrayID);


        if (result.Flag)
        {

            result.Data.TrayNo = data.TrayID;
            result.Data.StageNo = data.Stage.ToString();
            var str = result.Data.ToString();
            return new GrpcReturn<string>
            {
                Data = str,
                IsSuccess = true
            };
        }
        else
        {
            data.ErrorMsg = $"{data.Stage} {data.TrayID} {IotMsgConst.FmtTestError}，{result.Msg} ";
            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode = data.ErrorMsg,
                    EquipType = IotEquipType.FMT.ToString(),
                    ProtobufType=IotProtobufType.HK_OCVFMT.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.Num.ToString()
            } });
            return new GrpcReturn<string>
            {
                Msg = result.Msg,
            };
        }
    }

    public async Task<GrpcReturn<string>> CheckNGResult(HkWriteInstruct data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.CheckNGResult(data.TrayID);


        if (result.Flag)
        {


            return new GrpcReturn<string>
            {
                Msg = result.Code.ToString(),
                IsSuccess = true
            };
        }
        else
        {

            return new GrpcReturn<string>
            {
                Msg = result.Code.ToString(),
            };
        }
    }
    /// <summary>
    /// 筛选机获取电芯数据
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<SelCellResult>> GetSelCellData(HkWriteInstruct data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<SelCellResult>
            {
                Msg = "Timeout",
                Code = 400
            };
        }
        var result = await _remoteHttpService.GetSelCellData(data.TrayID, data.Num.To<int>());


        if (result.Flag)
        {


            return new GrpcReturn<SelCellResult>
            {
                Data = result.Data,
                IsSuccess = true
            };
        }
        else
        {

            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode =$" {data.TrayID} {IotMsgConst.SelError}，{result.Msg} {result.Code}",
                    EquipType = IotEquipType.SEL.ToString(),
                    ProtobufType=IotProtobufType.HK_SEL.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.Num.ToString()
            } });

            return new GrpcReturn<SelCellResult>
            {
                Msg = result.Code.ToString(),
            };
        }
    }
    /// <summary>
    /// 提交筛选结果
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> CommitSelResult(HkWriteInstruct data)
    {
        if (_remoteHttpService.IsRemoteTimeout())
        {
            return new GrpcReturn<string>
            {
                Msg = "Timeout"
            };
        }
        var result = await _remoteHttpService.CommitSelResult(data.TrayID);


        if (result.Flag)
        {


            return new GrpcReturn<string>
            {
                Data = result.Data,
                IsSuccess = true
            };
        }
        else
        {

            await _manager.AddWarns(new List<IotEquipWarnDto> { new IotEquipWarnDto
            {
                 ErrorCode =$" {data.TrayID} {IotMsgConst.SelCommitError}，{result.Msg} {result.Code}",
                    EquipType = IotEquipType.SEL.ToString(),
                    ProtobufType=IotProtobufType.HK_SEL.ToString(),
                    ErrorTime = DateTime.Now,
                    EquipNum = data.Num.ToString()
            } });
            return new GrpcReturn<string>
            {
                Msg = result.Code.ToString(),
            };
        }
    }

   
    #endregion
}
